home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / nroff / escape.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  17KB  |  1,062 lines

  1. /*
  2.  *    escape.c - Escape and special character input processing portion of
  3.  *               nroff word processor
  4.  *
  5.  *    adapted for atariST/TOS by Bill Rosenkranz 11/89
  6.  *    net:    rosenkra@hall.cray.com
  7.  *    CIS:    71460,17
  8.  *    GENIE:    W.ROSENKRANZ
  9.  *
  10.  *    original author:
  11.  *
  12.  *    Stephen L. Browning
  13.  *    5723 North Parker Avenue
  14.  *    Indianapolis, Indiana 46220
  15.  *
  16.  *    history:
  17.  *
  18.  *    - Originally written in BDS C;
  19.  *    - Adapted for standard C by W. N. Paul
  20.  *    - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
  21.  */
  22.  
  23. #undef NRO_MAIN                    /* extern globals */
  24.  
  25. #include <stdio.h>
  26. #include "nroff.h"
  27.  
  28.  
  29. /*------------------------------*/
  30. /*    expesc            */
  31. /*------------------------------*/
  32. expesc (p, q)
  33. char   *p;
  34. char   *q;
  35. {
  36.  
  37. /*
  38.  *    Expand escape sequences
  39.  */
  40.  
  41.     register char  *s;
  42.     register char  *t;
  43.     register char  *pstr;
  44.     register int    i;
  45.     register int    val;
  46.     register int    autoinc;
  47.     char        c;
  48.     char        fs[5];                /* for font change */
  49.     char        nrstr[20];
  50.     char        fmt[20];
  51.     char        name[10];
  52.     int        nreg;
  53.     char           *pfs;
  54.     int        inc;
  55.     int        tmp;
  56.     char        delim;
  57.  
  58.  
  59.     s = p;
  60.     t = q;
  61.  
  62.  
  63.     /*
  64.      *   if escape parsing is not on, just copy string
  65.      */
  66.     if (dc.escon == NO)
  67.     {
  68.         while (*s != EOS)
  69.         {
  70.             *t++ = *s++;
  71.         }
  72.         *t = EOS;
  73.         strcpy (p, q);
  74.  
  75.         return;
  76.     }
  77.  
  78.  
  79.     /*
  80.      *   do it...
  81.      */
  82.     while (*s != EOS)
  83.     {
  84.         if (*s != dc.escchr)
  85.         {
  86.             /*
  87.              *   not esc, continue...
  88.              */
  89.             *t++ = *s++;
  90.         }
  91.  
  92.  
  93.         else if (*(s + 1) == dc.escchr)
  94.         {
  95.             /*
  96.              *   \\            escape escape
  97.              */
  98.             *t++ = *s++;
  99.             ++s;
  100.         }
  101.  
  102.  
  103.         else if (*(s + 1) == 'n')
  104.         {
  105.             /*
  106.              *   \nx, \n(xx        register
  107.              *
  108.              *   first check for \n+... or \n-... (either form)
  109.              */
  110.             s += 2;
  111.             autoinc = 0;
  112.             if (*s == '+')
  113.             {
  114.                 autoinc = 1;
  115.                 s += 1;
  116.             }
  117.             if (*s == '-')
  118.             {
  119.                 autoinc = -1;
  120.                 s += 1;
  121.             }
  122.  
  123.  
  124.  
  125.             /*
  126.              *   was this \nx or \n(xx form?
  127.              */
  128.             if (isalpha (*s))
  129.             {
  130.                 /*
  131.                  *   \nx form. find reg (a-z)
  132.                  */
  133.                 nreg = tolower (*s) - 'a';
  134.  
  135.  
  136.                 /*
  137.                  *   was this \n+x or \n-x? if so, do the
  138.                  *   auto incr
  139.                  */
  140.                 if (autoinc > 0)
  141.                     dc.nr[nreg] += dc.nrauto[nreg];
  142.                 else if (autoinc < 0)
  143.                     dc.nr[nreg] -= dc.nrauto[nreg];
  144.  
  145.                 /*
  146.                  *   display format
  147.                  */
  148.                 if (dc.nrfmt[nreg] == '1')
  149.                 {
  150.                     /*
  151.                      *   normal decimal digits
  152.                      */
  153.                     t += itoda (dc.nr[nreg], t, 6) - 1;
  154.                 }
  155.                 else if (dc.nrfmt[nreg] == 'i')
  156.                 {
  157.                     /*
  158.                      *   lower roman
  159.                      */
  160.                     t += itoroman (dc.nr[nreg], t, 24) - 1;
  161.                 }
  162.                 else if (dc.nrfmt[nreg] == 'I')
  163.                 {
  164.                     /*
  165.                      *   upper roman
  166.                      */
  167.                     t += itoROMAN (dc.nr[nreg], t, 24) - 1;
  168.                 }
  169.                 else if (dc.nrfmt[nreg] == 'a')
  170.                 {
  171.                     /*
  172.                      *   lower letters
  173.                      */
  174.                     t += itoletter (dc.nr[nreg], t, 12) - 1;
  175.                 }
  176.                 else if (dc.nrfmt[nreg] == 'A')
  177.                 {
  178.                     /*
  179.                      *   upper letters
  180.                      */
  181.                     t += itoLETTER (dc.nr[nreg], t, 12) - 1;
  182.                 }
  183.                 else if (dc.nrfmt[nreg] & 0x80)
  184.                 {
  185.                     /*
  186.                      *   zero-filled decimal
  187.                      */
  188.                     sprintf (fmt, "%%0%dld",
  189.                         (int)(dc.nrfmt[nreg] & 0x7F));
  190.                     fmt[5] = '\0';
  191.                     sprintf (nrstr, fmt, (long) dc.nr[nreg]);
  192.                     tmp = dc.nrfmt[nreg] & 0x7F;
  193.                     nrstr[tmp] = '\0';
  194.  
  195.                     strcpy (t, nrstr);
  196.                     t += strlen (nrstr);
  197.                 }
  198.                 else
  199.                 {
  200.                     /*
  201.                      *   normal (default)
  202.                      */
  203.                     t += itoda (dc.nr[nreg], t, 6) - 1;
  204.                 }
  205.                 ++s;
  206.             }
  207.             else if (*s == '%')
  208.             {
  209.                 /*
  210.                  *   \n% form. find index into reg struct
  211.                  */
  212.                 nreg = findreg ("%");
  213.                 if (nreg < 0)
  214.                 {
  215.                     fprintf (err_stream,
  216.                         "***%s: no register match\n",
  217.                         myname);
  218.                     err_exit (-1);
  219.                 }
  220.  
  221.  
  222.                 /*
  223.                  *   was this \n+% or \n-%? if so, do the
  224.                  *   auto incr
  225.                  */
  226.                 if (autoinc > 0)
  227.                     rg[nreg].rval += rg[nreg].rauto;
  228.                 else if (autoinc < 0)
  229.                     rg[nreg].rval -= rg[nreg].rauto;
  230.  
  231.  
  232.                 /*
  233.                  *   display format
  234.                  */
  235.                 if (rg[nreg].rfmt == '1')
  236.                 {
  237.                     /*
  238.                      *   normal decimal digits
  239.                      */
  240.                     t += itoda (rg[nreg].rval, t, 6) - 1;
  241.                 }
  242.                 else if (rg[nreg].rfmt == 'i')
  243.                 {
  244.                     /*
  245.                      *   lower roman
  246.                      */
  247.                     t += itoroman (rg[nreg].rval, t, 24) - 1;
  248.                 }
  249.                 else if (rg[nreg].rfmt == 'I')
  250.                 {
  251.                     /*
  252.                      *   upper roman
  253.                      */
  254.                     t += itoROMAN (rg[nreg].rval, t, 24) - 1;
  255.                 }
  256.                 else if (rg[nreg].rfmt == 'a')
  257.                 {
  258.                     /*
  259.                      *   lower letters
  260.                      */
  261.                     t += itoletter (rg[nreg].rval, t, 12) - 1;
  262.                 }
  263.                 else if (rg[nreg].rfmt == 'A')
  264.                 {
  265.                     /*
  266.                      *   upper letters
  267.                      */
  268.                     t += itoLETTER (rg[nreg].rval, t, 12) - 1;
  269.                 }
  270.                 else if (rg[nreg].rfmt & 0x80)
  271.                 {
  272.                     /*
  273.                      *   zero-filled decimal
  274.                      */
  275.                     sprintf (fmt, "%%0%dld",
  276.                         (int)(rg[nreg].rfmt & 0x7F));
  277.                     fmt[5] = '\0';
  278.                     sprintf (nrstr, fmt, (long) rg[nreg].rval);
  279.                     tmp = rg[nreg].rfmt & 0x7F;
  280.                     nrstr[tmp] = '\0';
  281.  
  282.                     strcpy (t, nrstr);
  283.                     t += strlen (nrstr);
  284.                 }
  285.                 else
  286.                 {
  287.                     /*
  288.                      *   normal (default)
  289.                      */
  290.                     t += itoda (rg[nreg].rval, t, 6) - 1;
  291.                 }
  292.                 s += 1;
  293.             }
  294.             else if (*s == '(')
  295.             {
  296.                 /*
  297.                  *   \n(xx form. find index into reg struct
  298.                  */
  299.                 s += 1;
  300.                 name[0] = *s;
  301.                 name[1] = *(s + 1);
  302.                 if (name[1] == ' '  || name[1] == '\t'
  303.                 ||  name[1] == '\n' || name[1] == '\r')
  304.                     name[1] = '\0';
  305.                 name[2] = '\0';
  306.                 nreg = findreg (name);
  307.                 if (nreg < 0)
  308.                 {
  309.                     fprintf (err_stream,
  310.                         "***%s: no register match\n",
  311.                         myname);
  312.                     err_exit (-1);
  313.                 }
  314.                 
  315.  
  316.                 /*
  317.                  *   was this \n+(xx or \n-(xx? if so, do the
  318.                  *   auto incr
  319.                  */
  320.                 if (rg[nreg].rflag & RF_WRITE)
  321.                 {
  322.                     if (autoinc > 0)
  323.                         rg[nreg].rval += rg[nreg].rauto;
  324.                     else if (autoinc < 0)
  325.                         rg[nreg].rval -= rg[nreg].rauto;
  326.                 }
  327.  
  328.  
  329.                 /*
  330.                  *   display format
  331.                  */
  332.                 if (rg[nreg].rfmt == '1')
  333.                 {
  334.                     /*
  335.                      *   normal decimal digits
  336.                      */
  337.                     t += itoda (rg[nreg].rval, t, 6) - 1;
  338.                 }
  339.                 else if (rg[nreg].rfmt == 'i')
  340.                 {
  341.                     /*
  342.                      *   lower roman
  343.                      */
  344.                     t += itoroman (rg[nreg].rval, t, 24) - 1;
  345.                 }
  346.                 else if (rg[nreg].rfmt == 'I')
  347.                 {
  348.                     /*
  349.                      *   upper roman
  350.                      */
  351.                     t += itoROMAN (rg[nreg].rval, t, 24) - 1;
  352.                 }
  353.                 else if (rg[nreg].rfmt == 'a')
  354.                 {
  355.                     /*
  356.                      *   lower letters
  357.                      */
  358.                     t += itoletter (rg[nreg].rval, t, 12) - 1;
  359.                 }
  360.                 else if (rg[nreg].rfmt == 'A')
  361.                 {
  362.                     /*
  363.                      *   upper letters
  364.                      */
  365.                     t += itoLETTER (rg[nreg].rval, t, 12) - 1;
  366.                 }
  367.                 else if (rg[nreg].rfmt & 0x80)
  368.                 {
  369.                     /*
  370.                      *   zero-filled decimal
  371.                      */
  372.                     sprintf (fmt, "%%0%dld",
  373.                         (int)(rg[nreg].rfmt & 0x7F));
  374.                     fmt[5] = '\0';
  375.                     sprintf (nrstr, fmt, (long) rg[nreg].rval);
  376.                     tmp = rg[nreg].rfmt & 0x7F;
  377.                     nrstr[tmp] = '\0';
  378.  
  379.                     strcpy (t, nrstr);
  380.                     t += strlen (nrstr);
  381.                 }
  382.                 else
  383.                 {
  384.                     /*
  385.                      *   normal (default)
  386.                      */
  387.                     t += itoda (rg[nreg].rval, t, 6) - 1;
  388.                 }
  389.                 s += 2;
  390.             }
  391.         }
  392.  
  393.  
  394.         else if (*(s + 1) == '\"')
  395.         {
  396.             /*
  397.              *   \"            comment
  398.              */
  399.             *s = EOS;
  400.             *t = *s;
  401.  
  402.             return;
  403.         }
  404.  
  405.  
  406.         else if (*(s + 1) == '*')
  407.         {
  408.             /*
  409.              *   \*x, \*(xx        string
  410.              */
  411.             s += 2;
  412.             if (*s == '(')
  413.             {
  414.                 /*
  415.                  *   \*(xx form
  416.                  */
  417.                 s += 1;
  418.                 name[0] = *s;
  419.                 name[1] = *(s + 1);
  420.                 name[2] = '\0';
  421.                 pstr = getstr (name);
  422.                 if (!pstr)
  423.                 {
  424.                     fprintf (err_stream,
  425.                         "***%s: string not found\n",
  426.                         myname);
  427.                     err_exit (-1);
  428.                 }
  429.                 while (*pstr)
  430.                     *t++ = *pstr++;
  431.                 s += 2;
  432.             }
  433.             else
  434.             {
  435.                 /*
  436.                  *   \*x form
  437.                  */
  438.                 name[0] = *s;
  439.                 name[1] = '\0';
  440.                 pstr = getstr (name);
  441.                 if (!pstr)
  442.                 {
  443.                     fprintf (err_stream,
  444.                         "***%s: string not found\n",
  445.                         myname);
  446.                     err_exit (-1);
  447.                 }
  448.                 while (*pstr)
  449.                     *t++ = *pstr++;
  450.                 s += 1;
  451.             }
  452.         }
  453.  
  454.  
  455.         else if (*(s + 1) == 'f')
  456.         {
  457.             /*
  458.              *   \fx        font
  459.              */
  460.             s += 2;
  461.             pfs = fs;        /* set up ret string */
  462.             fs[0] = '\0';
  463.  
  464.             /*
  465.              *  it parses 1-2 char of s and returns esc seq for
  466.              *  \fB and \fR (\fI is same as \fB)
  467.              */
  468.             fontchange (*s, pfs);
  469.  
  470.             /*
  471.              *   imbed the atari (vt52) escape seq
  472.              */
  473.             while (*pfs)
  474.                 *t++ = *pfs++;
  475.             ++s;            /* skip B,I,R,S,P */
  476.         }
  477.  
  478.  
  479.         else if (*(s + 1) == '(')
  480.         {
  481.             /*
  482.              *   \(xx        special char
  483.              */
  484.             s  += 2;
  485.  
  486.             /*
  487.              *   it returns num char to skip and sets c to
  488.              *   the ascii value of the char
  489.              */
  490.             inc = specia